/*
 * Copyright (C) 2022-2022. Huawei Technologies Co., Ltd. All rights reserved.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.openlookeng.service.impl;

import cn.hutool.http.HttpUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.openlookeng.core.boot.dto.LoginUserInfoDTO;
import com.openlookeng.core.boot.jwt.model.Audience;
import com.openlookeng.core.boot.utils.FileUploadUtils;
import com.openlookeng.core.boot.utils.JwtTokenUtil;
import com.openlookeng.core.mp.base.BaseServiceImpl;
import com.openlookeng.entity.SysFile;
import com.openlookeng.exception.BizException;
import com.openlookeng.mapper.FileMapper;
import com.openlookeng.qo.FileQO;
import com.openlookeng.service.IFileService;
import com.openlookeng.utils.LinuxShellUtils;
import com.openlookeng.vo.FileVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;

import java.math.BigDecimal;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class FileServiceImpl
        extends BaseServiceImpl<FileMapper, SysFile>
        implements IFileService
{
    @Resource
    private Audience audience;
    @Value("${openlookeng.fileDir}")
    private String fileDir;

    @Override
    public IPage<FileVO> selectFilePage(FileQO file)
    {
        QueryWrapper<SysFile> queryWrapper = getQueryChainWrapper(file);
        IPage respPge = this.page(new Page<>(file.getPageNo(), file.getPageSize()), queryWrapper);
        return respPge;
    }

    @Override
    public List<SysFile> listFileBySystemUpLoad()
    {
        LambdaQueryWrapper<SysFile> queryWrapper = new LambdaQueryWrapper();
        queryWrapper.eq(SysFile::getCreateUserId, 0);
        queryWrapper.orderByDesc(SysFile::getId);
        return this.list(queryWrapper);
    }

    @Override
    public List<SysFile> listFileNoPage(FileQO qo)
    {
        LambdaQueryWrapper<SysFile> wrapper = new LambdaQueryWrapper<>();
        LoginUserInfoDTO currentLoginUser = JwtTokenUtil.getCurrentLoginUser(audience);
        //online
        if (1 == qo.getUpgradeWay()) {
            wrapper.eq(SysFile::getCreateUserId, 0);
        }
        else { //offline
            wrapper.eq(SysFile::getCreateUserId, currentLoginUser.getId());
        }
        List<SysFile> sysFiles = baseMapper.selectList(wrapper);
        return sysFiles;
    }

    @Override
    public SysFile uploadConfigFile(MultipartFile multipartFile, Integer clusterId, String version)
    {
        try {
            String filePath = LinuxShellUtils.deployPath + "configFile/" + clusterId + "/";
            String fileName = FileUploadUtils.getFileName(multipartFile);
            FileUploadUtils.upload(fileDir + filePath, multipartFile);
            SysFile sysFile = new SysFile();
            sysFile.setFilePath(filePath + fileName);
            return sysFile;
        }
        catch (Exception e) {
            log.error("uploadConfigFile err:{}", e.getMessage());
            throw new BizException("配置文件上传失败!");
        }
    }

    @Override
    public void getNewVersion()
    {
        try {
            String url = "https://download.openlookeng.io/?C=M&O=D";
            Document doc = Jsoup.connect(url).get();
            Elements elements = doc.getElementById("list").getElementsByClass("link");
            List<String> versionList = elements.stream().map(a -> {
                return a.getElementsByTag("a").get(0).text().replaceAll("/", "");
            }).filter(b -> b.contains("1.")).collect(Collectors.toList());
            String version = versionList.get(0);
            List<SysFile> sysFileList = this.listFileBySystemUpLoad();
            SysFile sysFile = sysFileList.stream().filter(a -> a.getVersion().equalsIgnoreCase(version)).findFirst().orElse(null);
            if (sysFile == null) {
                String downLoadUrl = "https://download.openlookeng.io/" + version + "/hetu-server-" + version + ".tar.gz";
                sysFile = new SysFile();
                sysFile.setDownloadUrl(downLoadUrl);
                sysFile.setCreateUserId(BigDecimal.ZERO.intValue());
                sysFile.setVersion(version);
                String fileName = downLoadUrl.substring(downLoadUrl.lastIndexOf("/") + 1);
                if (StringUtils.isBlank(sysFile.getFilePath())) {
                    String filePath = fileDir + "/download/" + fileName;
                    java.io.File file = new java.io.File(filePath);
                    if (!file.exists()) {
                        log.info("start download openlookeng install package,version:{}!", sysFile.getVersion());
                        HttpUtil.downloadFile(downLoadUrl, filePath);
                        log.info("download openlookeng package over,version:{}!", sysFile.getVersion());
                    }
                    sysFile.setFilePath(filePath);
                }
                this.save(sysFile);
            }
        }
        catch (Exception e) {
            log.error("getNewVersion err:{}", e.getMessage());
        }
    }
}
